#include "WaterProgressBar.h"

#include<QPainter>
#include<QPainterPath>
#include<QDebug>
//#define WAY 1
//为何创建此类代替成员变量？
//因为每次在.h文件中改变成员变量的时候都会重新编译，一旦涉及到很多成员变量发生改变的动作时，对程序的负担很大
//为了优化这个问题，在cpp文件中创建类，然后把类作为成员变量，这样就能解决
class SWaterProgressBarPaivate
{
public:
    SWaterProgressBarPaivate()
        :size(0)
        ,minimun(0)
        ,maximun(100)
        ,value(0)
        ,textvisiable(true)
        ,phi(0)
    {}
    int size;
    QRect drawRect;
    int minimun;
    int maximun;
    int value;
    bool textvisiable;
    qreal phi;
};

WaterProgressBar::WaterProgressBar(QWidget *parent)
    :QWidget(parent)
{
    resize(100,100);
    d.reset(new SWaterProgressBarPaivate);
    auto f  =font();
    f.setPointSize(23);
    setFont(f);
    startTimer(50);
}

WaterProgressBar::~WaterProgressBar()
{
    //delete d;
}

//静态图形的绘制
void WaterProgressBar::paintEvent(QPaintEvent *ev)
{
    QPainter painter(this);
    //设置反锯齿
    painter.setRenderHint(QPainter::RenderHint::Antialiasing);
#if WAY==1
    painter.translate(d->size/2,d->size/2);
#endif
    //绘制静态图形
    drawBackground(&painter);
    drawProgress(&painter);
    drawText(&painter);

}

void WaterProgressBar::drawBackground(QPainter *painter)
{
    //取消画笔
    painter->setPen(Qt::PenStyle::NoPen);
    //绘制静态的界面
    //绘制背景
    int size=qMin(width(),height());
    painter->setBrush(QBrush(qRgb(40,40,40)));
#if WAY == 1
    QRect drawRect(-d->size/2,-d->size/2,d->size,d->size);
#else
    QRect drawRect(0,0,d->size,d->size);
#endif
    qInfo()<<" 12";
    painter->drawEllipse(drawRect);
}

void WaterProgressBar::drawProgress(QPainter *painter)
{
    //求当前进度绘制的y坐标（h）
    qreal ratio=static_cast<qreal>(d->value-d->minimun)/(d->maximun-d->minimun);
#if WAY==1
    int h=d->size/2-ratio*d->size;
#else
    int h=d->size-ratio*d->size;
#endif
    painter->setBrush(QBrush(qRgb(96,170,235)));
    //绘制当前进度
    QPainterPath progressArea;
    QPainterPath progressArea1;
#if WAY==1
    progressArea.addRect(-d->size/2,h,d->size,d->size/2-h);
#else
    //progressArea.addRect(0,h,d->size,d->size-h);
    progressArea.moveTo(0,d->size);
    for (int x = 0; x < d->size; ++x)
    {
        progressArea.lineTo(x,4*qSin(0.05*x+d->phi)+h);
    }
    progressArea.lineTo(d->size,d->size);

    progressArea1.moveTo(0,d->size);
    for (int x = 0; x < d->size; ++x)
    {
        progressArea1.lineTo(x,4*qSin(0.05*x+d->phi+2)+h);
    }
    progressArea1.lineTo(d->size,d->size);
#endif


    //绘图区域矩形
    QPainterPath drawArea;
    drawArea.addEllipse(d->drawRect);

    painter->setBrush(QBrush(qRgb(58,85,107)));
    painter->drawPath(drawArea.intersected(progressArea));
    painter->setBrush(QBrush(qRgb(96,170,235)));
    painter->drawPath(drawArea.intersected(progressArea1));
}

void WaterProgressBar::drawText(QPainter *painter)
{
    if(d->textvisiable)
    {
        painter->setPen(QPen(Qt::white,1));
        int precision=1;
        if(static_cast<qreal>(d->value-d->minimun)/(d->maximun-d->minimun)*100==100)
        {
            precision=0;
        }
        painter->drawText(d->drawRect,Qt::AlignCenter,QString("%1%").
                          arg(static_cast<qreal>(d->value-d->minimun)/(d->maximun-d->minimun)*100,0,'f',precision));
        //10/(100- -100)-->10/200
        //(10- -100)/(100- -100)
    }
}

//数据的改变与获取
void WaterProgressBar::resizeEvent(QResizeEvent *ev)
{
    d->size=qMin(width(),height());
#if WAY==1
    d->drawRect=QRect(-d->size/2,-d->size/2,d->size,d->size);
#else
    d->drawRect=QRect(0,0,d->size,d->size);
#endif

}

void WaterProgressBar::timerEvent(QTimerEvent *ev)
{
    d->phi+=0.5;
    if(d->phi>360)
    {
        d->phi=0;
    }
    update();
}

int WaterProgressBar::Minimun() const
{
    return d->minimun;
}

int WaterProgressBar::Maximun() const
{
    return d->maximun;
}

int WaterProgressBar::value() const
{
    return d->value;
}

void WaterProgressBar::setRange(int minimun, int maximun)
{
    //考虑了传值大小颠倒的情况
    if(d->minimun==minimun&&d->maximun==maximun)
    {
        return;
    }
    d->maximun=qMax(minimun,maximun);
    d->minimun=qMin(minimun,maximun);
}

void WaterProgressBar::setMinimun(int minimun)
{
    //若传的最小值都比最大值大，则范围变为Minimun-Minimun
    setRange(minimun,qMax(minimun,d->maximun));
}

void WaterProgressBar::setMaximun(int maximun)
{
    //若传的最大值都比最小值小，则范围变为maximun-maximun
    setRange(qMin(maximun,d->minimun),maximun);
}

void WaterProgressBar::setValue(int value)
{
    if(d->value==value||value>d->maximun||value<d->minimun)
        return;
    d->value=value;
    emit valueChanged(value);
    update();
}

bool WaterProgressBar::isTextVisiable() const
{
    return d->textvisiable;
}

void WaterProgressBar::setTextVisiable(bool visiable)
{
    d->textvisiable=visiable;
}
